import Foundation
import CoreLocation
import UIKit
import Photos

// 兼容性扩展：如未来官方实现可移除
extension CLLocationCoordinate2D: Hashable {
    public func hash(into hasher: inout Hasher) {
        hasher.combine(latitude)
        hasher.combine(longitude)
    }
    public static func == (lhs: CLLocationCoordinate2D, rhs: CLLocationCoordinate2D) -> Bool {
        lhs.latitude == rhs.latitude && lhs.longitude == rhs.longitude
    }
}

// MARK: - 可序列化的照片数据模型
struct SerializablePhotoData: Codable {
    let id: String
    let creationDate: Date
    let location: SerializableLocationInfo?
    let hasGeocodingAttempted: Bool?
    // 🚀 优化：不保存图片数据，只保存元数据
    // let thumbnailData: Data?
    // let originalImageData: Data?
    
    init(from photoData: PhotoData) {
        self.id = photoData.id
        self.creationDate = photoData.creationDate
        self.location = photoData.location.map { SerializableLocationInfo(from: $0) }
        self.hasGeocodingAttempted = photoData.hasGeocodingAttempted
        // self.thumbnailData = photoData.thumbnail?.jpegData(compressionQuality: 0.8)
        // self.originalImageData = photoData.originalImage?.jpegData(compressionQuality: 0.9)
    }
    
    func toPhotoData(asset: PHAsset) -> PhotoData {
        return PhotoData(
            id: id,
            creationDate: creationDate,
            location: location?.toLocationInfo(),
            thumbnail: nil, // 不预加载图片
            originalImage: nil, // 不预加载图片
            asset: asset,
            hasGeocodingAttempted: hasGeocodingAttempted
        )
    }
    
    /// 🚀 优化：快速创建PhotoData，不需要PHAsset（用于开机快速加载）
    func toPhotoDataWithoutAsset() -> PhotoData? {
        // 创建一个临时的PHAsset，只用于满足PhotoData的初始化要求
        // 实际使用时，图片会通过延迟加载获取
        let tempAsset = PHAsset.fetchAssets(withLocalIdentifiers: [id], options: nil).firstObject
        
        guard let asset = tempAsset else {
            print("⚠️ 无法获取照片资产: \(id)")
            return nil
        }
        
        return PhotoData(
            id: id,
            creationDate: creationDate,
            location: location?.toLocationInfo(),
            thumbnail: nil, // 延迟加载
            originalImage: nil, // 延迟加载
            asset: asset,
            hasGeocodingAttempted: hasGeocodingAttempted
        )
    }
}

// MARK: - 可序列化的位置信息
struct SerializableLocationInfo: Codable {
    let latitude: Double
    let longitude: Double
    let country: String?
    let state: String?
    let city: String?
    let address: String?
    
    init(from locationInfo: LocationInfo) {
        self.latitude = locationInfo.coordinate.latitude
        self.longitude = locationInfo.coordinate.longitude
        self.country = locationInfo.country
        self.state = locationInfo.state
        self.city = locationInfo.city
        self.address = locationInfo.address
    }
    
    func toLocationInfo() -> LocationInfo {
        return LocationInfo(
            coordinate: CLLocationCoordinate2D(latitude: latitude, longitude: longitude),
            country: country,
            state: state,
            city: city,
            address: address
        )
    }
}

struct PhotoData: Identifiable, Equatable {
    let id: String
    let creationDate: Date
    var location: LocationInfo?  // 改为var使其可变
    var hasGeocodingAttempted: Bool?  // 是否尝试过地理编码
    private var _thumbnail: UIImage?
    private var _originalImage: UIImage?
    let asset: PHAsset
    
    // 🚀 延迟加载图片
    var thumbnail: UIImage? {
        get {
            if _thumbnail == nil {
                // 需要时再加载缩略图
                return nil // 暂时返回nil，后续实现异步加载
            }
            return _thumbnail
        }
        set {
            _thumbnail = newValue
        }
    }
    
    var originalImage: UIImage? {
        get {
            if _originalImage == nil {
                // 需要时再加载原图
                return nil // 暂时返回nil，后续实现异步加载
            }
            return _originalImage
        }
        set {
            _originalImage = newValue
        }
    }
    
    // 初始化方法
    init(id: String, creationDate: Date, location: LocationInfo?, thumbnail: UIImage?, originalImage: UIImage?, asset: PHAsset, hasGeocodingAttempted: Bool? = nil) {
        self.id = id
        self.creationDate = creationDate
        self.location = location
        self.hasGeocodingAttempted = hasGeocodingAttempted
        self._thumbnail = thumbnail
        self._originalImage = originalImage
        self.asset = asset
    }
    
    // Hashable 实现
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    
    static func == (lhs: PhotoData, rhs: PhotoData) -> Bool {
        return lhs.id == rhs.id
    }
}

struct LocationInfo: Hashable {
    let coordinate: CLLocationCoordinate2D
    let country: String?
    let state: String?
    let city: String?
    let address: String?
    
    var displayName: String {
        if let city = city {
            return city
        } else if let state = state {
            return state
        } else if let country = country {
            return country
        } else {
            return "未知地点"
        }
    }
    
    var fullAddress: String {
        var components: [String] = []
        
        if let address = address {
            components.append(address)
        }
        if let city = city {
            components.append(city)
        }
        if let state = state {
            components.append(state)
        }
        if let country = country {
            components.append(country)
        }
        
        return components.isEmpty ? "未知地点" : components.joined(separator: ", ")
    }
    
    // Hashable 实现
    func hash(into hasher: inout Hasher) {
        hasher.combine(coordinate.latitude)
        hasher.combine(coordinate.longitude)
        hasher.combine(country)
        hasher.combine(state)
        hasher.combine(city)
    }
    
    static func == (lhs: LocationInfo, rhs: LocationInfo) -> Bool {
        return lhs.coordinate.latitude == rhs.coordinate.latitude &&
               lhs.coordinate.longitude == rhs.coordinate.longitude &&
               lhs.country == rhs.country &&
               lhs.state == rhs.state &&
               lhs.city == rhs.city
    }
}

// MARK: - 时间轴数据结构

struct TimelineGroup: Identifiable {
    let id = UUID()
    let date: Date
    let photos: [PhotoData]
    let location: LocationInfo?
    
    var dateString: String {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy年MM月dd日"
        return formatter.string(from: date)
    }
    
    var monthString: String {
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy年MM月"
        return formatter.string(from: date)
    }
    
    var dayString: String {
        let formatter = DateFormatter()
        formatter.dateFormat = "dd日"
        return formatter.string(from: date)
    }
}

// MARK: - 照片统计信息

struct PhotoStatistics {
    let totalPhotos: Int
    let totalLocations: Int
    let dateRange: ClosedRange<Date>?
    let mostFrequentLocation: LocationInfo?
    let mostActiveMonth: String?
    
    init(photos: [PhotoData]) {
        self.totalPhotos = photos.count
        
        let uniqueLocations = Set(photos.compactMap { $0.location })
        self.totalLocations = uniqueLocations.count
        
        if let firstDate = photos.map({ $0.creationDate }).min(),
           let lastDate = photos.map({ $0.creationDate }).max() {
            self.dateRange = firstDate...lastDate
        } else {
            self.dateRange = nil
        }
        
        // 计算最频繁的地点
        let locationCounts = Dictionary(grouping: photos.compactMap { $0.location }) { $0 }
            .mapValues { $0.count }
        
        self.mostFrequentLocation = locationCounts.max(by: { $0.value < $1.value })?.key
        
        // 计算最活跃的月份
        let monthCounts = Dictionary(grouping: photos) { photo in
            let formatter = DateFormatter()
            formatter.dateFormat = "yyyy-MM"
            return formatter.string(from: photo.creationDate)
        }.mapValues { $0.count }
        
        if let mostActiveMonth = monthCounts.max(by: { $0.value < $1.value })?.key {
            let formatter = DateFormatter()
            formatter.dateFormat = "yyyy-MM"
            if let date = formatter.date(from: mostActiveMonth) {
                formatter.dateFormat = "yyyy年MM月"
                self.mostActiveMonth = formatter.string(from: date)
            } else {
                self.mostActiveMonth = mostActiveMonth
            }
        } else {
            self.mostActiveMonth = nil
        }
    }
}

// MARK: - 扩展 PhotoStatistics

extension PhotoStatistics {
    var dateRangeText: String {
        guard let dateRange = dateRange else { return "未知" }
        
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy年MM月"
        
        let startDate = formatter.string(from: dateRange.lowerBound)
        let endDate = formatter.string(from: dateRange.upperBound)
        
        if startDate == endDate {
            return startDate
        } else {
            return "\(startDate) - \(endDate)"
        }
    }
} 